﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using Microsoft.Win32;

namespace CSNN
{
    public delegate void VoidDelegat();   
    
    /// <summary>
    /// Логика взаимодействия для MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        #region Члены класса

        /// <summary>
        /// Элемент для отображения нейронной сети
        /// </summary>
        private NeuralNetShow NetShow;
        
        /// <summary>
        /// Нейронная сеть приложения
        /// </summary>
        private NeuralNetwork CurrentNetwork;

        /// <summary>
        /// Флаг загрузки нейронной сети
        /// </summary>
        public bool isNetLoaded;

        /// <summary>
        /// Флаг загрузки из файла
        /// </summary>
        public bool isInFile;

        /// <summary>
        /// Путь к файлу нейронной сети
        /// </summary>
        public string filePath;

        /// <summary>
        /// Короткое имя файла
        /// </summary>
        public string fileName;

        #endregion

        public MainWindow()
        {
            InitializeComponent();

            this.CurrentNetwork = new NeuralNetwork();
            this.isNetLoaded = false;
            this.isInFile = false;
            this.filePath = "";
            this.fileName = "";
        }

        /// <summary>
        /// Обработчки команды "Закрыть"
        /// </summary>
        private void CloseWindow_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// Обработчик команды "Новая сеть"
        /// </summary>
        private void NewNetwork_Click(object sender, RoutedEventArgs e)
        {
            this.isInFile = false;
            this.isNetLoaded = false;

            VoidDelegat dl = new VoidDelegat(this.UpdateMainWindow);
            
            WindowNeuralNetCreate WinCreate = new WindowNeuralNetCreate();
            WinCreate.Owner = this;
            WinCreate.SetNet(this.CurrentNetwork, dl);
            WinCreate.Show();
        }

        /// <summary>
        /// Обработчик клика кнопки "Обучающие множества"
        /// </summary>
        private void OpenTrainingSet_Click(object sender, RoutedEventArgs e)
        {
            if (CurrentNetwork.IsBuild == false)
            {
                ShowMessageNoNet();
                return;
            }           
            WindowTrainingImages WinTrain = new WindowTrainingImages();
            WinTrain.Owner = this;
            WinTrain.SetImagesDemension(CurrentNetwork.NeuralLayers[0].NeuronsDemension, 
                                        CurrentNetwork.NeuralLayers[CurrentNetwork.LayersCount-1].NeuronsCount,
                                        CurrentNetwork.TrainingImages,
                                        new VoidDelegat(UpdateMainWindow));
            WinTrain.Show();
        }

        /// <summary>
        /// Обновление главного окна
        /// </summary>
        public void UpdateMainWindow()
        {
            if (!isNetLoaded)
            {
                NetShow = new NeuralNetShow(CurrentNetwork, ImageNetShow);
                NetShow.Draw();
                isNetLoaded = true;
            }
        }

        /// <summary>
        /// Обработчик клика кнопки "Обучение"
        /// </summary>
        private void Education_Click(object sender, RoutedEventArgs e)
        {
            if (CurrentNetwork.IsBuild == false)
            {
                ShowMessageNoNet();
                return;
            }

            Education WinEducation = new Education();
            WinEducation.SetNet(CurrentNetwork);
            WinEducation.Owner = this;
            WinEducation.Show();
        }

        /// <summary>
        /// Обработчик клика кнопки "Распознание"
        /// </summary>
        private void Recignition_Click(object sender, RoutedEventArgs e)
        {
            if (CurrentNetwork.IsBuild == false)
            {
                ShowMessageNoNet();
                return;
            }

            Rocognition WinRecog = new Rocognition();
            WinRecog.Owner = this;
            WinRecog.SetImagesDemension(CurrentNetwork.NeuralLayers[0].NeuronsDemension, CurrentNetwork);
            WinRecog.Show();
        }

        /// <summary>
        /// Обработчик команды "Открыть"
        /// </summary>
        private void OpenNetwork_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog OpenDlg = new OpenFileDialog();
            OpenDlg.DefaultExt = ".fnn";
            OpenDlg.Filter = "File of Neural Network (.fnn)|*.fnn";

            if (OpenDlg.ShowDialog() == true)
            {
                this.filePath = OpenDlg.FileName;
                this.CurrentNetwork.LoadFromFile(this.filePath);
                this.fileName = OpenDlg.SafeFileName;
                this.isInFile = true;
                this.isNetLoaded = true;
                this.UpdateMainWindow();
            }
        }

        /// <summary>
        /// Обработчик команды "Сохранить"
        /// </summary>
        private void SaveNetwork_Click(object sender, RoutedEventArgs e)
        {
            if (CurrentNetwork.IsBuild == true)
            {
                if (this.isInFile == false)
                {
                    SaveFileDialog SaveDlg = new SaveFileDialog();
                    SaveDlg.DefaultExt = ".fnn";
                    SaveDlg.Filter = "File of Neural Network (.fnn)|*.fnn";

                    if (SaveDlg.ShowDialog() == true)
                    {
                        this.filePath = SaveDlg.FileName;
                        this.CurrentNetwork.SaveToFile(this.filePath);
                        this.fileName = SaveDlg.SafeFileName;
                        this.isInFile = true;
                        //LabelFilePath.Text = this.fileName;
                    }
                }
                else
                {
                    this.CurrentNetwork.SaveToFile(filePath);
                }
            }
            else
            {
                ShowMessageNoNet();
            }
        }

        /// <summary>
        /// Обработчик команды "Сохранить как"
        /// </summary>
        private void SaveAsNetwork_Click(object sender, RoutedEventArgs e)
        {
            if (CurrentNetwork.IsBuild == true)
            {
                SaveFileDialog SaveAsDlg = new SaveFileDialog();
                SaveAsDlg.DefaultExt = ".fnn";
                SaveAsDlg.Filter = "File of Neural Network (.fnn)|*.fnn";

                if (SaveAsDlg.ShowDialog() == true)
                {
                    this.filePath = SaveAsDlg.FileName;
                    this.CurrentNetwork.SaveToFile(this.filePath);
                    this.fileName = SaveAsDlg.SafeFileName;
                    //LabelFilePath.Text = this.fileName;
                }
            }
            else
            {
                ShowMessageNoNet();
            }
        }

        /// <summary>
        /// Обработчик команды "Закрыть файл"
        /// </summary>
        private void CloseFile_Click(object sender, RoutedEventArgs e)
        {
            this.CurrentNetwork = new NeuralNetwork();
            this.isInFile = false;
            this.filePath = "";
            this.fileName = "";
            this.isNetLoaded = false;
            this.NetShow = null;
            this.ImageNetShow.Source = null;
        }

        /// <summary>
        /// Обработчик команды "Помощь"
        /// </summary>
        private void ShowHelp_Click(object sender, RoutedEventArgs e)
        {

        }

        /// <summary>
        /// Обработчик команды "О программе"
        /// </summary>
        private void ShowAbout_Click(object sender, RoutedEventArgs e)
        {
            WindowAbout winAbout = new WindowAbout();
            winAbout.Owner = this;
            winAbout.Show();
        }

        public void LoadSettings(StreamReader fileSettingsPath)
        {
        }

        private void NetInformation(object sender, RoutedEventArgs e)
        {
            if (CurrentNetwork.IsBuild == false)
            {
                ShowMessageNoNet();
                return;
            }

            WindowNeuralNetInfo winInfo = new WindowNeuralNetInfo();
            winInfo.SetNeuralNetInfo(CurrentNetwork);
            winInfo.Owner = this;
            winInfo.Show();
        }

        protected void ShowMessageNoNet()
        {
            MessageBox.Show("Нет созданной или открытой сети для работы.", "Внимание", MessageBoxButton.OK, MessageBoxImage.Exclamation);
        }
    }
}
